Skip to content

feat(api): add CompletePromptOptions parameter to completePrompt method#901

Open
easonLiangWorldedtech wants to merge 3 commits into
Zoo-Code-Org:mainfrom
easonLiangWorldedtech:feat/abort-signal-core/complete-prompt
Open

feat(api): add CompletePromptOptions parameter to completePrompt method#901
easonLiangWorldedtech wants to merge 3 commits into
Zoo-Code-Org:mainfrom
easonLiangWorldedtech:feat/abort-signal-core/complete-prompt

Conversation

@easonLiangWorldedtech

@easonLiangWorldedtech easonLiangWorldedtech commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #615 — Core plumbing for abort signal in completePrompt path.

This PR adds an optional second parameter (CompletePromptOptions) to all provider completePrompt methods, enabling future abort signal and timeout support without breaking existing callers.

Changes

New: CompletePromptOptions interface

export interface CompletePromptOptions extends Pick<ApiHandlerCreateMessageMetadata, "abortSignal"> {
    /** Optional timeout override (ms) — falls back to provider default if omitted */
    timeoutMs?: number
}

Design note: Rather than passing the full ApiHandlerCreateMessageMetadata as issue #615 described, this PR introduces a minimal interface that only exposes abortSignal and timeoutMs. This keeps the API surface clean while still enabling abort signal pass-through. The metadata pattern used in the stream path (via ApiHandlerCreateMessageMetadata) is already handled separately.

Updated files

  • src/api/index.ts — Added CompletePromptOptions, updated SingleCompletionHandler.completePrompt signature
  • 25+ provider implementations — All now accept options?: CompletePromptOptions (backward compatible, optional)
  • src/utils/single-completion-handler.ts — Forwards options to the handler

Tests (Task.spec.ts)

  • Updated existing assertions from toBeInstanceOf(AbortSignal)toBe(task.currentRequestAbortController!.signal) for signal identity verification
  • Added new test: "should create a fresh AbortController for each sequential request" confirming controllers are not reused across requests

Acceptance criteria (from #615)

Related

Summary by CodeRabbit

  • New Features

    • Added optional structured controls to non-streaming prompt completion, including timeoutMs and abortSignal.
    • Updated completePrompt to accept optional metadata/options and ensured the single-completion flow forwards these options to the selected provider.
  • Tests

    • Strengthened cancellation behavior tests to require the exact abortSignal instance and confirmed retries use a fresh, initially un-aborted signal.
    • Updated prompt enhancement tests to expect completePrompt to be called with an explicit undefined options argument when omitted.
    • Added coverage verifying FakeAIHandler delegates completePrompt with the correct prompt/options.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

CompletePromptOptions adds optional abort-signal and timeout metadata to completePrompt. The shared completion utility and provider handlers accept the options, while fake-handler forwarding and abort-signal tests are updated.

Changes

Complete prompt options

Layer / File(s) Summary
Completion contract and forwarding
src/api/index.ts, src/utils/single-completion-handler.ts, src/api/providers/fake-ai.ts, src/api/providers/__tests__/fake-ai.spec.ts
Defines CompletePromptOptions and forwards optional options through completion and fake handlers, with delegation tests.
Provider completion signatures
src/api/providers/*.ts
Updates provider imports and completePrompt signatures to accept optional CompletePromptOptions while preserving existing request behavior.
Abort-signal validation
src/core/task/__tests__/Task.spec.ts, src/utils/__tests__/enhance-prompt.spec.ts
Checks exact abort-signal identity, fresh controllers across sequential requests, and the updated completion call shape.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • Issue 616 — Covers related completePrompt abort-signal metadata propagation.
  • Issue 617 — Addresses abort propagation through the same provider completion APIs.
  • Issue 618 — Updates abort-signal metadata handling for overlapping providers.

Possibly related PRs

Suggested reviewers: navedmerchant

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR meets #615's core goals by adding the options parameter, forwarding it, and updating tests for signal identity and fresh controllers.
Out of Scope Changes check ✅ Passed The changes stay focused on abort-signal plumbing and related tests, with no clear unrelated feature work.
Title check ✅ Passed The title clearly states the main API change and is concise and specific.
Description check ✅ Passed It includes the linked issue, summary, implementation details, and tests; only the template headings and some optional sections differ.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/api/providers/base-openai-compatible-provider.ts (1)

215-229: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Thread CompletePromptOptions into these completion requests.

abortSignal and timeoutMs are defined on CompletePromptOptions, but every completePrompt here drops options, so caller cancellation and per-call timeouts never reach the SDK request.

  • src/api/providers/base-openai-compatible-provider.ts#L215-L229
  • src/api/providers/opencode-go.ts#L488-L537
  • src/api/providers/openrouter.ts#L577-L606
  • src/api/providers/poe.ts#L141-L147
  • src/api/providers/qwen-code.ts#L330-L341
  • src/api/providers/requesty.ts#L207-L221
  • src/api/providers/unbound.ts#L195-L209
  • src/api/providers/vercel-ai-gateway.ts#L120-L136
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/providers/base-openai-compatible-provider.ts` around lines 215 - 229,
Thread CompletePromptOptions through each completePrompt implementation so
abortSignal and timeoutMs reach the underlying SDK completion request. Update
the request construction or invocation in
src/api/providers/base-openai-compatible-provider.ts lines 215-229,
src/api/providers/opencode-go.ts lines 488-537, src/api/providers/openrouter.ts
lines 577-606, src/api/providers/poe.ts lines 141-147,
src/api/providers/qwen-code.ts lines 330-341, src/api/providers/requesty.ts
lines 207-221, src/api/providers/unbound.ts lines 195-209, and
src/api/providers/vercel-ai-gateway.ts lines 120-136, reusing each provider’s
existing request options and preserving current completion behavior.
🧹 Nitpick comments (1)
src/core/task/__tests__/Task.spec.ts (1)

2235-2252: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Simplify the mock stream factory.

The custom mock implementation manually overrides the async iterator protocol, but for await loops rely exclusively on the [Symbol.asyncIterator]() method. Since that method returns a native generator, your custom next(), return(), and throw() methods are bypassed as dead code, and callCount is never actually incremented here.

You can safely simplify this to a standard async generator function, which naturally fulfills the AsyncGenerator contract and correctly increments your counter as intended:

♻️ Proposed refactor
-				const mockStreamFactory = () => {
-					return {
-						async *[Symbol.asyncIterator]() {
-							yield { type: "text", text: `response ${callCount}` }
-						},
-						async next() {
-							callCount++
-							return { done: true, value: { type: "text", text: `response ${callCount - 1}` } }
-						},
-						async return() {
-							return { done: true, value: undefined }
-						},
-						async throw(e: any) {
-							throw e
-						},
-						[Symbol.asyncDispose]: async () => {},
-					} as AsyncGenerator<ApiStreamChunk>
-				}
+				const mockStreamFactory = async function* (): AsyncGenerator<ApiStreamChunk> {
+					yield { type: "text", text: `response ${callCount}` }
+					callCount++
+				}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/task/__tests__/Task.spec.ts` around lines 2235 - 2252, Replace the
custom object returned by mockStreamFactory with a standard async generator
function. Move the callCount increment into the generator execution before
yielding the response, remove the manually defined next, return, throw, and
async iterator members, and preserve the existing response text and
AsyncGenerator<ApiStreamChunk> contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/api/providers/gemini.ts`:
- Line 579: All completePrompt implementations accept CompletePromptOptions but
do not propagate cancellation or timeout settings to their requests. Update
src/api/providers/gemini.ts:579 in completePrompt to pass abortSignal to
generateContent; src/api/providers/minimax.ts:292-295 in completePrompt to pass
the signal to client.messages.create; src/api/providers/mistral.ts:195 in
completePrompt to pass abortSignal and timeoutMs to client.chat.complete;
src/api/providers/native-ollama.ts:553-579 in completePrompt to pass abortSignal
to client.chat; src/api/providers/openai-codex.ts:1157 in completePrompt to use
options?.abortSignal for fetch, preserving the existing controller as fallback;
src/api/providers/openai-compatible.ts:200 in completePrompt to pass abortSignal
to generateText; and src/api/providers/openai-native.ts:1487-1585 in
completePrompt to use options?.abortSignal for responses.create instead of
relying solely on the shared controller.

---

Outside diff comments:
In `@src/api/providers/base-openai-compatible-provider.ts`:
- Around line 215-229: Thread CompletePromptOptions through each completePrompt
implementation so abortSignal and timeoutMs reach the underlying SDK completion
request. Update the request construction or invocation in
src/api/providers/base-openai-compatible-provider.ts lines 215-229,
src/api/providers/opencode-go.ts lines 488-537, src/api/providers/openrouter.ts
lines 577-606, src/api/providers/poe.ts lines 141-147,
src/api/providers/qwen-code.ts lines 330-341, src/api/providers/requesty.ts
lines 207-221, src/api/providers/unbound.ts lines 195-209, and
src/api/providers/vercel-ai-gateway.ts lines 120-136, reusing each provider’s
existing request options and preserving current completion behavior.

---

Nitpick comments:
In `@src/core/task/__tests__/Task.spec.ts`:
- Around line 2235-2252: Replace the custom object returned by mockStreamFactory
with a standard async generator function. Move the callCount increment into the
generator execution before yielding the response, remove the manually defined
next, return, throw, and async iterator members, and preserve the existing
response text and AsyncGenerator<ApiStreamChunk> contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 098310bc-c298-461e-b612-f08806baff20

📥 Commits

Reviewing files that changed from the base of the PR and between 50801da and 688319b.

📒 Files selected for processing (30)
  • src/api/index.ts
  • src/api/providers/anthropic-vertex.ts
  • src/api/providers/anthropic.ts
  • src/api/providers/base-openai-compatible-provider.ts
  • src/api/providers/bedrock.ts
  • src/api/providers/fake-ai.ts
  • src/api/providers/gemini.ts
  • src/api/providers/kenari.ts
  • src/api/providers/lite-llm.ts
  • src/api/providers/lm-studio.ts
  • src/api/providers/minimax.ts
  • src/api/providers/mistral.ts
  • src/api/providers/native-ollama.ts
  • src/api/providers/openai-codex.ts
  • src/api/providers/openai-compatible.ts
  • src/api/providers/openai-native.ts
  • src/api/providers/openai.ts
  • src/api/providers/opencode-go.ts
  • src/api/providers/openrouter.ts
  • src/api/providers/poe.ts
  • src/api/providers/qwen-code.ts
  • src/api/providers/requesty.ts
  • src/api/providers/unbound.ts
  • src/api/providers/vercel-ai-gateway.ts
  • src/api/providers/vscode-lm.ts
  • src/api/providers/xai.ts
  • src/api/providers/zoo-gateway.ts
  • src/core/task/__tests__/Task.spec.ts
  • src/utils/__tests__/enhance-prompt.spec.ts
  • src/utils/single-completion-handler.ts

Comment thread src/api/providers/gemini.ts
@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 15, 2026
Add optional second parameter to all provider completePrompt methods for future abort signal and timeout support.

- Add CompletePromptOptions interface with abortSignal and timeoutMs fields
- Update 25+ provider implementations to accept options?: CompletePromptOptions parameter
- Simplify providers to use basic request calls without signal/timeout logic
@easonLiangWorldedtech easonLiangWorldedtech force-pushed the feat/abort-signal-core/complete-prompt branch from 37133de to 62ed671 Compare July 16, 2026 12:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/api/providers/base-openai-compatible-provider.ts (1)

215-243: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Unused options parameter in completePrompt implementations.

Although the options parameter (containing abortSignal and timeoutMs) is now included in the completePrompt signature across all providers, it is never forwarded to the underlying SDK clients (e.g., OpenAI or Anthropic). As a result, network requests will not actually be aborted when the cancellation signal is triggered, defeating the objective of stopping requests after cancellation.

  • src/api/providers/base-openai-compatible-provider.ts#L215-L243: Pass the options to the OpenAI client call: await this.client.chat.completions.create(params, { signal: options?.abortSignal, timeout: options?.timeoutMs }).
  • src/api/providers/opencode-go.ts#L488-L545: Pass the options to both the Anthropic and OpenAI client calls.
  • src/api/providers/requesty.ts#L207-L226: Pass the options to the OpenAI client call.
  • src/api/providers/vercel-ai-gateway.ts#L120-L144: Pass the options to the OpenAI client call.
  • src/api/providers/xai.ts#L145-L163: Pass the options to the Responses API client call.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/providers/base-openai-compatible-provider.ts` around lines 215 - 243,
Forward CompletePromptOptions.abortSignal and timeoutMs to every underlying SDK
request: update completePrompt in
src/api/providers/base-openai-compatible-provider.ts (215-243), both Anthropic
and OpenAI calls in src/api/providers/opencode-go.ts (488-545), the OpenAI call
in src/api/providers/requesty.ts (207-226), the OpenAI call in
src/api/providers/vercel-ai-gateway.ts (120-144), and the Responses API call in
src/api/providers/xai.ts (145-163). Use each client’s request options so
cancellation and timeouts are applied.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/api/providers/base-openai-compatible-provider.ts`:
- Around line 215-243: Forward CompletePromptOptions.abortSignal and timeoutMs
to every underlying SDK request: update completePrompt in
src/api/providers/base-openai-compatible-provider.ts (215-243), both Anthropic
and OpenAI calls in src/api/providers/opencode-go.ts (488-545), the OpenAI call
in src/api/providers/requesty.ts (207-226), the OpenAI call in
src/api/providers/vercel-ai-gateway.ts (120-144), and the Responses API call in
src/api/providers/xai.ts (145-163). Use each client’s request options so
cancellation and timeouts are applied.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e539678-aff9-4a10-a391-e6ceb6abf6a6

📥 Commits

Reviewing files that changed from the base of the PR and between 37133de and 62ed671.

📒 Files selected for processing (31)
  • src/api/index.ts
  • src/api/providers/__tests__/fake-ai.spec.ts
  • src/api/providers/anthropic-vertex.ts
  • src/api/providers/anthropic.ts
  • src/api/providers/base-openai-compatible-provider.ts
  • src/api/providers/bedrock.ts
  • src/api/providers/fake-ai.ts
  • src/api/providers/gemini.ts
  • src/api/providers/kenari.ts
  • src/api/providers/lite-llm.ts
  • src/api/providers/lm-studio.ts
  • src/api/providers/minimax.ts
  • src/api/providers/mistral.ts
  • src/api/providers/native-ollama.ts
  • src/api/providers/openai-codex.ts
  • src/api/providers/openai-compatible.ts
  • src/api/providers/openai-native.ts
  • src/api/providers/openai.ts
  • src/api/providers/opencode-go.ts
  • src/api/providers/openrouter.ts
  • src/api/providers/poe.ts
  • src/api/providers/qwen-code.ts
  • src/api/providers/requesty.ts
  • src/api/providers/unbound.ts
  • src/api/providers/vercel-ai-gateway.ts
  • src/api/providers/vscode-lm.ts
  • src/api/providers/xai.ts
  • src/api/providers/zoo-gateway.ts
  • src/core/task/__tests__/Task.spec.ts
  • src/utils/__tests__/enhance-prompt.spec.ts
  • src/utils/single-completion-handler.ts
🚧 Files skipped from review as they are similar to previous changes (17)
  • src/utils/single-completion-handler.ts
  • src/api/providers/bedrock.ts
  • src/api/providers/qwen-code.ts
  • src/api/providers/vscode-lm.ts
  • src/api/providers/openai-codex.ts
  • src/api/providers/mistral.ts
  • src/api/providers/zoo-gateway.ts
  • src/api/providers/openai.ts
  • src/api/providers/openrouter.ts
  • src/api/providers/minimax.ts
  • src/api/providers/anthropic-vertex.ts
  • src/api/providers/kenari.ts
  • src/api/providers/unbound.ts
  • src/api/providers/openai-compatible.ts
  • src/api/providers/native-ollama.ts
  • src/core/task/tests/Task.spec.ts
  • src/api/providers/openai-native.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(api): abort signal core plumbing — interface, Task.ts, single-completion-handler

2 participants